package grex.fitnessfunctions.Regression;

import grex.GP;
import grex.Prediction;
import grex.fitnessfunctions.FitnessFunction;
import grex.fitnessfunctions.IFitnessFunction;
import grex.genes.GeneException;

import java.io.Serializable;

/**
 *
 * @author rik
 */
public class RMSE_Fitness extends FitnessFunction implements IFitnessFunction, Serializable{

    public RMSE_Fitness() {
        super(FitnessFunction.RMSE);
    }
       public RMSE_Fitness(String name,Double instanceKey) {
        super(name,instanceKey);
    }
    
    double avgActualValue = 0; //Used to normalize the error

    @Override
    protected double calcPredictionError(Prediction prediction, double targetValue) {
       return Math.pow(prediction.getPrediction()-targetValue,2);
    }
    @Override
    protected double normalizeTotalError(double totalError){
        return Math.sqrt(totalError / getNrOfInstances()) / getAverageActualValue();
    }
/*
    public double calcFitness(GP gp) throws GeneException {
        gp.train();
        int size=gp.getPcTrain().values().size();
        if(avgActualValue == 0){
            for(Prediction p:gp.getPcTrain().values()){
                avgActualValue += p.getTargetValue();
            }
            avgActualValue = avgActualValue/gp.getPcTrain().values().size();
        }
        
        double mse = 0;

        double cases=0;
        for(Prediction p:gp.getPcTrain().values()){
            if(Math.random()<gp.getOptions().getTOMBOLA_PERCENT()){
                mse+= Math.pow(p.getPrediction()-p.getTargetValue(),2);
                cases++;
            }
        }
        mse = 100 * Math.sqrt(mse/cases)/avgActualValue;
        
        if(gp.getLength()>gp.getOptions().getMAX_TREE_SIZE())
            mse += (gp.getLength()-gp.getOptions().getMAX_TREE_SIZE())*gp.getOptions().getPUNISHMENT_FOR_LENGTH()*50;


        return  mse + gp.getLength()*gp.getOptions().getPUNISHMENT_FOR_LENGTH();
    }*/
}
